package com.weishenai.customerassistant.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.weishenai.customerassistant.common.Result;
import com.weishenai.customerassistant.entity.MetersResult;
import com.weishenai.customerassistant.service.ElectricalService;
import com.weishenai.customerassistant.service.FactFinderService;
import com.weishenai.customerassistant.service.MetersResultsService;
import com.weishenai.customerassistant.utils.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.lang.reflect.Field;
import java.util.Set;

@Api(tags = "管理系统_勘察报告勘察报告结果")
@Slf4j
@RestController
@RequestMapping("/result")
public class MetersResultController extends BaseController{
    @Autowired
    private ElectricalService electricalService;
    @Autowired
    private MetersResultsService metersResultsService;

    @Value("${file.imageSavePath}")
    private String fileSavePath;

    @ApiOperation("修改一条勘察勘察报告结果信息")
    @PostMapping("/update")
    public Object updateOneMetersResult(@RequestBody MetersResult metersResult) {
        if (checkMetersResult(metersResult)) {
            metersResult.setCreatedTime(DateUtil.getTime());
            Integer result = metersResultsService.insertOneMetersResult(metersResult);
            return result > 0 ? Result.success() : Result.failed("失败");
        } else return Result.failed("检查勘察报告结果不符合标准！");
    }

    @PreAuthorize("hasAuthority('surveyReport:list:changeState')")
    @ApiOperation("修改一条勘察勘察报告结果状态信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "勘察报告的id"),
            @ApiImplicitParam(name = "state", value = "新的勘察报告状态")
    })
    @PostMapping("/updateState/{id}/{state}")
    public Object updateOneMetersResultState(@PathVariable("id") Long id, @PathVariable("state") String state) {
        MetersResult metersResult = metersResultsService.selectById(id);
        metersResult.setState(state);
        if (checkMetersResult(metersResult)) {
            metersResultsService.updateById(metersResult);
            log.info("id为" + id + "的勘察报告修改新的状态为：" + state + "成功");
            return Result.success();
        } else return Result.failed("这条勘察报告勘察报告结果已经被删除或其他原因");
    }

    @PreAuthorize("hasAuthority('surveyReport:list:delete')")
    @ApiOperation("管理系统 根据id删除一条勘察报告结果信息")
    @ApiImplicitParam(name = "id", value = "id")
    @GetMapping("/delOneMetersResultById/{id}")
    public Object delOneMetersResultById(@PathVariable(name = "id") Long id) {
        //根据id查到这个勘察报告获取图片的url然后删除
        MetersResult metersResult = metersResultsService.selectById(id);
        if (metersResult == null) return Result.failed("订单id错误或已经被删除");
        String url = metersResult.getPowerSupplyPlan();//图片的url
        //分割url获取到  https://42.192.131.195:443/image/2022-02-15/image1164491511
        String[] urls = url.split("/");
        for (String s : urls) {
            log.info(s);
        }
        //拼接URL
        String photoUrl = fileSavePath + urls[4] + "/" + urls[5];
        log.info("被删除勘测单的图片URL：" + photoUrl);
        //删除这个图片
        boolean result = new File(photoUrl).delete();
        if (!result) return Result.failed("报告单手画图片删除失败！");
        return metersResultsService.delMetersResultById(id) > 0 ? Result.success() : Result.failed("失败");
    }

    @PreAuthorize("hasAuthority('surveyReport:list')")
    @ApiOperation("依据供电所查询所有的勘察报告结果数据（有关键字）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "substation", value = "所属供电所"),
            @ApiImplicitParam(name = "pageNum", value = "第几页"),
            @ApiImplicitParam(name = "pageSize", value = "每一页的数量"),
            @ApiImplicitParam(name = "keyWord", required = false, value = "是否需要模糊查询，如果为空则展示全部")
    })
    @GetMapping("/selectAll/{substation}/{pageNum}/{pageSize}/{keyWord}")
    public Object selectAll(@PathVariable(name = "substation") String substation, @PathVariable(name = "pageNum") Integer
            pageNum, @PathVariable(name = "pageSize") Integer pageSize, @PathVariable(name = "keyWord") String keyWord) {
        IPage<MetersResult> selectAllData = metersResultsService.selectAll(substation, pageNum, pageSize, keyWord);

        return Result.success(selectAllData);
    }

    @PreAuthorize("hasAuthority('surveyReport:list')")
    @ApiOperation("查询所有的勘察报告结果数据（没有关键字）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "substation", value = "所属供电所"),
            @ApiImplicitParam(name = "pageNum", value = "第几页"),
            @ApiImplicitParam(name = "pageSize", value = "每一页的数量"),
    })
    @GetMapping("/selectAll/{substation}/{pageNum}/{pageSize}")
    public Object selectAll(@PathVariable(name = "substation") String substation, @PathVariable(name = "pageNum") Integer
            pageNum, @PathVariable(name = "pageSize") Integer pageSize) {
        IPage<MetersResult> selectAllData = metersResultsService.selectAll(substation, pageNum, pageSize, null);
        log.info("查询所有勘察报告的结果共" + selectAllData.getTotal() + "条数据");
        return Result.success(selectAllData);
    }

    @PreAuthorize("hasAuthority('surveyReport:list')")
    @ApiOperation("日期间勘察报告查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "substation", value = "所属供电所"),
            @ApiImplicitParam(name = "pageNum", value = "第几页"),
            @ApiImplicitParam(name = "pageSize", value = "每一页的数量"),
            @ApiImplicitParam(name = "startDate", value = "开始日期 例如：2022-01-26"),
            @ApiImplicitParam(name = "endDate", value = "结束日期 ：2022-01-26")
    })
    @GetMapping("/selectByDate/{substation}/{startDate}/{endDate}/{pageNum}/{pageSize}")
    public Object selectByDate(@PathVariable(name = "substation") String substation, @PathVariable(name = "startDate") String startDate, @PathVariable("endDate") String endDate, @PathVariable(name = "pageNum") Integer
            pageNum, @PathVariable(name = "pageSize") Integer pageSize) {
        IPage<MetersResult> result = metersResultsService.selectByDate(substation, startDate, endDate, pageNum, pageSize);
        log.info("查询日期为" + startDate + "-" + endDate + "的勘察报告结果共" + result.getTotal() + "条数据");

        return Result.success(result);
    }

    @PreAuthorize("hasAuthority('surveyReport:list')")
    @ApiOperation("查询某一天的勘察报告查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "substation", value = "所属供电所"),
            @ApiImplicitParam(name = "pageNum", value = "第几页"),
            @ApiImplicitParam(name = "pageSize", value = "每一页的数量"),
            @ApiImplicitParam(name = "date", value = "查询日期日期.例如：2022-01-26"),
    })
    @GetMapping("/selectByDate/{substation}/{date}/{pageNum}/{pageSize}")
    public Object selectByOneDate(@PathVariable(name = "substation") String substation, @PathVariable("date") String date, @PathVariable(name = "pageNum") Integer
            pageNum, @PathVariable(name = "pageSize") Integer pageSize) {
        IPage<MetersResult> result = metersResultsService.selectByDate(substation, date + " 00:00:00", date + " 23:59:59", pageNum, pageSize);
        log.info("查询日期为" + date + "的勘察报告结果共" + result.getTotal() + "条数据");
        return Result.success(result);
    }

    @ApiOperation("基本信息统计,包括业务总量，昨日新增，勘察员数量")
    @GetMapping("/getBaseStatistics/{substation}")
    public Object getBaseStatistics(@PathVariable(name = "substation") String substation){
        return Result.success(metersResultsService.getBaseStatisticsInfo(substation));
    }

    @ApiOperation("统计每个供电所由多少人")
    @GetMapping("/getMeterResultStatistics")
    public Object getMeterResultStatistics() {
        return Result.success(metersResultsService.listMeterResultStatistics());
    }

    @ApiOperation("统计当前供电所的材料单使用情况")
    @GetMapping("/getMaterialTypeStatistics/{substationName}/{type}")
    public Object getMaterialTypeStatistics(@PathVariable(name = "substationName") String substationName, @PathVariable(name = "type") int type) {
        return Result.success(metersResultsService.listMeterTypeStatisticsBySubstation(substationName, type));
    }

    @ApiOperation("获取某供电所勘察人员工作记录")
    @GetMapping("/listMeterFactFinderStatisticsBySubstation/{substationName}/{type}")
    public Object listMeterFactFinderStatisticsBySubstation(@PathVariable(name = "substationName") String substationName, @PathVariable(name = "type") int type) {
        return Result.success(metersResultsService.listMeterFactFinderStatisticsBySubstation(substationName, type));
    }

    @ApiOperation("根据勘察员获取近一周工作记录")
    @GetMapping("/getFactFinderWeekJobStatistics/{substation}/{fact}")
    public Object getFactFinderWeekJob(@PathVariable(name = "substation") String substation, @PathVariable(name = "fact") String fact) {
        return Result.success(metersResultsService.getFactFinderWeekJob(substation, fact));
    }

    /**
     * 检查勘察报告结果是否符合插入标准
     *
     * @param metersResult 勘察报告
     * @return 是否符合
     */
    private boolean checkMetersResult(MetersResult metersResult) {
        log.info("开始检查勘察报告单信息是否符合标准...");
        Set<String> set = electricalService.selectNames();
        Class cls = metersResult.getClass();
        Field[] fields = cls.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];
            f.setAccessible(true);
            Object result = null;
            try {
                //获取字段结果
                result = (Object) f.get(metersResult);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                return false;
            }

            if (f.getName().equals("type") || f.getName().equals("lowPressureRod")) {
                continue;
            }

            //判断这个字段结果是不是在数据库当中
            if (f.getName().equals("transformerName")) {
                //不在数据库返回失败
                if (!set.contains(result)) {
                    log.info("属性名:" + f.getName() + "为" + result.toString() + ",不存在数据库，报告单检查失败！");
                    return false;
                }
            }
            //数据为空也返回失败
            if (result == null) {
                log.info("属性名:" + f.getName() + "为空，报告单检查失败！");
                return false;
            }
        }
        log.info("检查完成，勘察报告单符合标准");
        return true;
    }
}
